﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using System.Security.Permissions;
using System.Web.Caching;
using System.Collections.Specialized;
using System.IO;

namespace Vision.Utilities.ConsoleApp.PreCompilation
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.High)]
    public class CmsVirtualPathProvider : VirtualPathProvider
    {
        #region Ctor
        public CmsVirtualPathProvider()
            : base()
        {
        }
        #endregion

        #region Override Methods
        public override bool FileExists(string virtualPath)
        {
            if (IsSpecialPath(virtualPath))
                return (GetFile(virtualPath) as CmsVirtualFile).Exists;
            else
                return Previous.FileExists(virtualPath);
        }
        
        public override VirtualFile GetFile(string virtualPath)
        {
            if (IsSpecialPath(virtualPath))
                return new CmsVirtualFile(virtualPath);
            else
                return Previous.GetFile(virtualPath);
        }

        public override bool DirectoryExists(string virtualDir)
        {
            if (IsSpecialPath(virtualDir))
                return (GetDirectory(virtualDir) as CmsVirtualDirectory).Exists;
            else
                return Previous.DirectoryExists(virtualDir);
        }

        public override VirtualDirectory GetDirectory(string virtualDir)
        { 
            if (IsSpecialPath(virtualDir))
                return new CmsVirtualDirectory(virtualDir);
            else
                return Previous.GetDirectory(virtualDir);
        }

        public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            if (IsSpecialPath(virtualPath))
            {
                var fullPathDependencies = new List<string>();

                // Get the full path to all dependencies.
                foreach (string virtualDependency in virtualPathDependencies)
                { 
                    fullPathDependencies.Add(virtualDependency);
                }
                
                // Copy the virtual path into an array.
                var virtualPathList = new List<string>();
                virtualPathList.Add(HostingEnvironment.MapPath(virtualPath));

                // Remove Self Dependency, otherwise, will force self dependence, and affect memory.
                // Maybe cause session will be removed automatically. 
                if (fullPathDependencies.Any(c => c.Equals(virtualPath)))
                    fullPathDependencies.Remove(virtualPath);

                for (var index = 0; index < fullPathDependencies.Count; index++)
                {
                    var vp = fullPathDependencies[index];
                    var vpPhysical = HostingEnvironment.MapPath(vp);
                    if (File.Exists(vpPhysical))
                    {
                        if (!virtualPathList.Contains(vpPhysical))
                        {
                            virtualPathList.Add(vpPhysical);
                            fullPathDependencies.Remove(vp);
                        }
                    }
                }

                return new CacheDependency(virtualPathList.ToArray(), fullPathDependencies.ToArray(), utcStart);
                //return null;
            }
            else
                return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }

        #endregion

        #region Helper Methods
        internal static bool IsSpecialPath(string virtualPath)
        {
            //virtualPath = ReplaceReservedVirtualPath(virtualPath);
            //return VirtualPathUtility.ToAppRelative(virtualPath);
            //return SiteManager.Current.IsSpecialVirtualPath(virtualPath);
            return false;
        }
        #endregion
    }

}